package org.example.controller

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest
import org.springframework.http.HttpStatus
import org.springframework.test.web.reactive.server.WebTestClient
import spock.lang.Specification

@WebFluxTest(PongController)
class PongControllerSpec extends Specification {

    @Autowired
    WebTestClient webTestClient

    def "should return World for first request in a second"() {
        when:
        def response = webTestClient.get().uri("/pong")
                .header("X-Ping-Service-Name", "PingService1")
                .exchange()
                .expectStatus().isOk()
                .expectBody(String.class)
                .returnResult()
                .getResponseBody()

        then:
        response == "World"
    }

    def "should return 429 for second request in the same second"() {
        when:
        def firstResponse = webTestClient.get().uri("/pong")
                .header("X-Ping-Service-Name", "PingService1").exchange()
                .expectStatus().isOk().expectBody(String.class).returnResult().getResponseBody()
        def secondResponse = webTestClient.get().uri("/pong")
                .header("X-Ping-Service-Name", "PingService2").exchange()
                .expectStatus().isEqualTo(HttpStatus.TOO_MANY_REQUESTS).expectBody(String.class).returnResult().getResponseBody()

        then:
        firstResponse == "World"
        secondResponse == null
    }

    def "should return World for requests in different seconds"() {
        setup:
        webTestClient.get().uri("/pong").header("X-Ping-Service-Name", "PingService1")
                .exchange().expectStatus().isOk()
                .expectBody(String.class).returnResult()

        // Wait for more than 1 second to ensure the next request is in a new second
        Thread.sleep(1100)

        when:
        def response = webTestClient.get().uri("/pong")
                .header("X-Ping-Service-Name", "PingService2")
                .exchange().expectStatus().isOk().expectBody(String.class).returnResult().getResponseBody()

        then:
        response == "World"
    }
}